using System;
using System.Collections.Generic;
using Microsoft.DirectX.DirectInput;
using Microsoft.Xna.Framework;
using System.Diagnostics;

namespace Soopah.Xna.Input
{
	/// <summary>
	/// A struct offering the current positions of as many as 3 thumbsticks on a PC gamepad or joystick
	/// </summary>
	/// <remarks>
	/// For unusual joysticks, these "thumbsticks" may be whatever the hardware-designer imagined;
	/// for example, Right.Y might be a jet-throttle and Right.X might be the rotational position of a steering wheel
	/// In other words, being in the list of Gamepads doesn't mean it looks anything like a Gamepad
	/// </remarks>
	public struct DirectInputThumbSticks
	{
		/// <summary>
		/// Check HasLeft, HasRight, etc before getting these values; will always be 0 if this gamepad lacks the requested thumbstick
		/// </summary>
		public Vector2 Left;
		public Vector2 Right;
		public Vector2 Third;
		//public Microsoft.Xna.Framework.Vector2 Fourth;

		public bool HasLeft;
		public bool HasRight;
		public bool HasThird;
		//public bool HasFourth;
        List<Vector2> Sticks;

        const float center = 256;//32767.5f;

		public DirectInputThumbSticks(Device device)
		{

            Sticks = new List<Vector2>();
			JoystickState t = device.CurrentJoystickState;
			HasLeft = false;
			Left = Vector2.Zero;
			HasRight = false;
			Right = Vector2.Zero;
			HasThird = false;
			Third = Vector2.Zero;

            try
            {
                if (device.Caps.NumberAxes > 0)
                {
                    HasLeft = true;
                    Left = new Vector2((t.X - center) / center, (t.Y - center) / center);
                    //Left = new Vector2((t.X - center), (t.Y - center));

                    if (device.Caps.NumberAxes > 2)
                    {
                        HasRight = true;
                        Right = new Vector2((t.Rx - center) / center, (t.Ry - center) / center);
                        //Right = new Vector2((t.Rx - center), (t.Ry - center));

                        if (device.Caps.NumberAxes > 4)
                        {
                            HasThird = true;
                            Third = new Vector2((t.Rz - center) / center, (t.Z - center) / center);
                            //Third = new Vector2((t.Rz - center), (t.Z - center));
                        }
                    }
                }
            }
            catch (Exception Ex)
            {
                Trace.WriteLine(Ex.Message);
                Trace.WriteLine(Ex.StackTrace);
            }
		}

        public DirectInputThumbSticks(Device device, ButtonSettings bSettings)
        {
            Sticks = new List<Vector2>(3);
            Sticks.Add(Vector2.Zero);
            Sticks.Add(Vector2.Zero);
            Sticks.Add(Vector2.Zero);

            HasLeft = false;
            Left = Vector2.Zero;
            HasRight = false;
            Right = Vector2.Zero;
            HasThird = false;
            Third = Vector2.Zero;

            try
            {
                JoystickState t = device.CurrentJoystickState;

                foreach (AnalogInput AI in bSettings.Sticks)
                {
                    //Get the X and Y depending on the Axis Setting;
                    Vector2 stick = Vector2.Zero;
                    switch (AI.XAxis)
                    {
                        case "X":
                            stick.X = (t.X - center) / center;
                            break;
                        case "Z":
                            stick.X = (t.Z - center) / center;
                            break;
                        case "Y":
                            stick.X = (t.Y - center) / center;
                            break;
                        case "Rz":
                            stick.X = (t.Rz - center) / center;
                            break;
                        case "Rx":
                            stick.X = (t.Rx - center) / center;
                            break;
                        case "Ry":
                            stick.X = (t.Ry - center) / center;
                            break;
                        case "Throttle":
                            stick.X = (t.GetSlider()[0] - center) / center;
                            break;

                    }
                    switch (AI.YAxis)
                    {
                        case "X":
                            stick.Y = (center - t.X) / center;
                            break;
                        case "Z":
                            stick.Y = (center - t.Z) / center;
                            break;
                        case "Y":
                            stick.Y = (center - t.Y) / center;
                            break;
                        case "Rz":
                            stick.Y = (center - t.Rz) / center;
                            break;
                        case "Rx":
                            stick.Y = (center - t.Rx) / center;
                            break;
                        case "Ry":
                            stick.Y = (center - t.Ry) / center;
                            break;
                        case "Throttle":
                            stick.Y = (center - t.GetSlider()[0]) / center;
                            break;
                    }
                    switch (AI.Index)
                    {
                        case 1:
                            HasLeft = true;
                            Left = stick;
                            //if (Left != Vector2.Zero)
                            //    Left.Normalize();
                            break;
                        case 2:
                            HasRight = true;
                            Right = stick;
                            //if (Right != Vector2.Zero)
                            //    Right.Normalize();
                            break;
                        case 3:
                            HasThird = true;
                            Third = stick;
                            //if (Third != Vector2.Zero)
                            //    Third.Normalize();
                            break;
                    }
                }

            }
            catch (Exception Ex)
            {
                Trace.WriteLine(Ex.Message);
                Trace.WriteLine(Ex.StackTrace);
            }
            

        }
    }
}
